package com.aiwhose.aiwhosefile.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.aiwhose.aiwhosecore.bean.Result;
import com.aiwhose.aiwhosefile.bean.FileQiniuSecurity;
import com.aiwhose.aiwhosefile.utils.QiniuYunUtils;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.aiwhose.aiwhosecore.bean.file.File;
import com.aiwhose.aiwhosefile.mapper.FileMapper;
import com.aiwhose.aiwhosefile.service.FileService;
import com.qiniu.storage.BucketManager;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 文件 服务层实现。
 *
 * @author 田国刚
 * @since 1.0.1
 */
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {

    @Resource
    FileMapper fileMapper;


    @Value("${qiniuyun.accessKey}")
    private String accessKey;
    @Value("${qiniuyun.secretKey}")
    private String secretKey;
    @Value("${qiniuyun.public.pu_bucket}")
    private String pu_bucket;
    @Value("${qiniuyun.public.pu_domainOfBucket}")
    private String pu_domainOfBucket;
    @Value("${qiniuyun.public.pu_region}")
    private String pu_region;
    @Value("${qiniuyun.private.pr_bucket}")
    private String pr_bucket;
    @Value("${qiniuyun.private.pr_domainOfBucket}")
    private String pr_domainOfBucket;
    @Value("${qiniuyun.private.pr_region}")
    private String pr_region;

    @Override
    public ArrayList<File> uploadFile(MultipartFile[] files, String user, String bucket) throws Exception {

        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);
        ArrayList<File> fileArrayList = new ArrayList<>();
        for (MultipartFile f : files) {
            File file = new File();
            String path = "AiTools/" + user + QiniuYunUtils.createPath(f.getOriginalFilename());

            file.setLocationPath(path);
            file.setFilename(f.getOriginalFilename());
            file.setLocationType("qiniuyun");
            file.setSize(String.valueOf(f.getSize()));
            file.setUrl(fileQiniuSecurity.getBucketUrl() + "/" + path);
            file.setUser(user);
            file.setAccessAuthority(fileQiniuSecurity.getType());
            file.setFileType(getfileType(f.getContentType()));
            file.setStr1("https://tgg.cloudtgg.com/cloud/202304180357020.jpeg");
            QiniuYunUtils.uploadQiniu(f.getBytes(), path, fileQiniuSecurity);
            fileArrayList.add(file);
        }
         fileMapper.insertBatch(fileArrayList, 30);
        return fileArrayList;

    }

    @Override
    public Result reUploadFile(MultipartFile[] files, String user, String path, String bucket) throws IOException {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);
        MultipartFile file = files[0];
        String s = QiniuYunUtils.reUploadQiniu(file.getBytes(), user, path, fileQiniuSecurity);
        QueryWrapper fileUpdateWrapper = new QueryWrapper();
        fileUpdateWrapper.eq(File::getUrl, path).eq(File::getLocationType, "qiniuyun").eq(File::getAccessAuthority, bucket);
        File reFile = fileMapper.selectOneByQuery(fileUpdateWrapper);
        reFile.setRemark(s);
        fileMapper.update(reFile);
//        刷新缓存
        String[] url = {path};
        QiniuYunUtils.refreshCache(url, fileQiniuSecurity);
        return Result.ok(s);
    }

    @Override
    public Result downloadFile(String path, Long time, String bucket) throws UnsupportedEncodingException {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);
        String download = QiniuYunUtils.download(path, time, fileQiniuSecurity);
        return Result.ok(download);
    }

    @Override
    public String getPrivateUrl(String path) throws UnsupportedEncodingException {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity("private");
        String download = QiniuYunUtils.getPrivateUrl(path, fileQiniuSecurity);
        return download;
    }

    @Override
    public Result deleteFile(String[] path, String bucket) {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);
//        数据库删除
        QueryWrapper fileUpdateWrapper = new QueryWrapper();
        fileUpdateWrapper.eq(File::getLocationType, "qiniuyun").in(File::getLocationPath, path)
                .eq(File::getAccessAuthority, bucket);
        int remove = fileMapper.deleteByQuery(fileUpdateWrapper);

//        存储删除
        if (remove>0) {
            Result map = QiniuYunUtils.deleteFilesFromQiniu(path, fileQiniuSecurity);
            return map;
        } else {
            return Result.error("数据库中未能成功删除");
        }
    }

    /**
     * @param maxLimit  每次迭代的长度限制，最大1000，推荐值 1000   maxLimit=1000
     * @param prefix    文件名前缀 prefix      = "kmu/2022/";
     * @param delimiter 指定目录分隔符，列出所有公共前缀（模拟列出目录效果）。缺省值为空字符串 delimiter   String delimiter = "";
     * @param bucket    空间标记（public/private）
     * @return 文件列表
     */
    @Override
    public Result getFileList(Integer maxLimit, String prefix, String delimiter, String bucket) {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);

        BucketManager.FileListIterator fileList = QiniuYunUtils.getFileList(maxLimit, prefix, delimiter, fileQiniuSecurity);
        return Result.ok(fileList);
    }

    /**
     * @param file 文件参数
     * @return
     */
    @Override
    public Result getFileListData(File file, String user) {
        QueryWrapper fileQueryWrapper = new QueryWrapper();
        fileQueryWrapper
                .like(File::getFilename, file.getFilename(), ObjectUtil.isNotEmpty(file.getFilename()))
                .like(File::getLocationPath, file.getLocationPath(), ObjectUtil.isNotEmpty(file.getLocationPath()))
                .eq(File::getLocationType, "qiniuyun")
                .eq(File::getUser, user)
                .eq(File::getUrl, file.getUrl(), ObjectUtil.isNotEmpty(file.getUrl()))
                .eq(File::getAccessAuthority, file.getAccessAuthority(), ObjectUtil.isNotEmpty(file.getAccessAuthority()));
        List<File> list = fileMapper.selectListByQuery(fileQueryWrapper);

        return Result.ok(list);
    }

    @Override
    public String getToken(FileQiniuSecurity fileQiniuSecurity, String path) {

        return QiniuYunUtils.getToken(fileQiniuSecurity, path);

    }

    @Override
    public String getUserToken(String userId, String type) {
        return null;
    }

    @Override
    public String getQiniuAuthorization(String bucket, String url, String method, byte[] body) {
        FileQiniuSecurity fileQiniuSecurity = getFileQiniuSecurity(bucket);
        return QiniuYunUtils.getQiniuAuthorization(fileQiniuSecurity, url, method, body);
    }


    public FileQiniuSecurity getFileQiniuSecurity(String bucket) {
        FileQiniuSecurity fileQiniuSecurity = new FileQiniuSecurity();
        fileQiniuSecurity.setSecretKey(secretKey);
        fileQiniuSecurity.setAccessKey(accessKey);
        if ("private".equals(bucket)) {
            fileQiniuSecurity.setBucketName(pr_bucket);
            fileQiniuSecurity.setBucketUrl(pr_domainOfBucket);
            fileQiniuSecurity.setBucketRegion(pr_region);
        } else {
            fileQiniuSecurity.setBucketName(pu_bucket);
            fileQiniuSecurity.setBucketUrl(pu_domainOfBucket);
            fileQiniuSecurity.setBucketRegion(pu_region);
        }
        return fileQiniuSecurity;
    }

    String getfileType(String mimeType) {
        if (ObjectUtil.isEmpty(mimeType)) {
            return "未获取到文件格式";
        }
        String fileType = "";
        if (mimeType.equalsIgnoreCase("image/jpeg") ||
                mimeType.equalsIgnoreCase("image/pjpeg") ||
                mimeType.equalsIgnoreCase("image/png") ||
                mimeType.equalsIgnoreCase("image/gif") ||
                mimeType.equalsIgnoreCase("image/bmp")) {
            fileType = "Image";
        } else if (mimeType.equalsIgnoreCase("application/pdf")) {
            fileType = "PDF";
        } else if (mimeType.equalsIgnoreCase("application/msword") ||
                mimeType.equalsIgnoreCase("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
            fileType = "Word";
        } else if (mimeType.equalsIgnoreCase("application/vnd.ms-excel") ||
                mimeType.equalsIgnoreCase("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
            fileType = "Excel";
        } else if (mimeType.equalsIgnoreCase("application/vnd.ms-powerpoint") ||
                mimeType.equalsIgnoreCase("application/vnd.openxmlformats-officedocument.presentationml.presentation")) {
            fileType = "PowerPoint";
        } else if (mimeType.equalsIgnoreCase("text/plain")) {
            fileType = "Text";
        } else if (mimeType.equalsIgnoreCase("application/zip") ||
                mimeType.equalsIgnoreCase("application/x-zip-compressed")) {
            fileType = "ZIP";
        } else if (mimeType.equalsIgnoreCase("application/x-rar-compressed")) {
            fileType = "RAR";
        } else if (mimeType.equalsIgnoreCase("video/mp4") ||
                mimeType.equalsIgnoreCase("video/webm") ||
                mimeType.equalsIgnoreCase("video/ogg") ||
                mimeType.equalsIgnoreCase("video/quicktime") ||
                mimeType.equalsIgnoreCase("video/x-msvideo") ||
                mimeType.equalsIgnoreCase("video/x-ms-wmv")) {
            fileType = "Video";
        } else {
            fileType = "Unknown";
        }
        return fileType;
    }

}
